﻿// --- Copyright (c) 2010 Steven Hartgers ---
// Copyright (C) 2010 Steven Hartgers All rights are reserved.
// Author contact: fiinix00/at\gmail.com
// ------------------------------------------------------------------------
// This program is free software: you can redistribute it and/or modify 
// it under the terms of the GNU General Public License as published by 
// the Free Software Foundation, either version 3 of the License, or 
// (at your option) any later version. 
//  
// This program is distributed in the hope that it will be useful, 
// but WITHOUT ANY WARRANTY; without even the implied warranty of 
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
// GNU General Public License for more detail
//  
// You should have received a copy of the GNU General Public License 
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
// ------------------------------------------------------------------------
// COPYRIGHT NOTICE: This copyright notice may NOT be removed, obscured or modified 
// without written consent from the author.
// --- End copyright notice --- 


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.IO;
using System.Net;
using Hack.Attributes;
using System.ComponentModel;

namespace Hack.Comunication.MessagePub
{
    [API(ProviderUrl = "http://messagepub.com"), Helper, Description(@"
                                Free Trial Account          Paid Account
Money to use towards messages	$2 (our gift to you)	    Unlimited, Pay As You Go
Powered by 'messagepub'         message	Bottom of emails	None
Ads in messages	                Sometimes	                Never
Email	 	                    Free***                     $0.0015*
Google Chat	Free	            Free***                     $0.0015*
AIM	                            Free***	                    $0.0015*
Twitter	 	                    Free***	                    $0.0015*
Phone** (US-Only)	            $0.07*	                    $0.07*
SMS (US-Only)	                $0.07*	                    $0.07*


* This is the price per message sent with the API.

** Your recipient will get a phone call and the text you sent out will be read to him (text-to-speech).

*** (Up to 5000 msg a month)")]
    public class Client
    {

        private string apiKey;
        private string baseUrl;

        // Constructor
        public Client(string yourAPIKey)
        {
            baseUrl = "http://messagepub.com";
            apiKey = yourAPIKey;
        }

        // Properties
        public string APIKey
        {
            get
            {
                return apiKey;
            }

            set
            {
                apiKey = value;
            }
        }

        // Public Methods

        // returns HTTP Status Code
        public string createNotification(Notification note)
        {
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(baseUrl + "/notifications.xml");
            req.PreAuthenticate = true;
            req.Credentials = new NetworkCredential(apiKey, "password");
            req.Method = "POST";
            req.ContentType = "text/xml";
            req.Accept = "text/xml";
            Stream s = req.GetRequestStream();
            string postData = note.getXML();
            s.Write(System.Text.Encoding.ASCII.GetBytes(postData), 0, postData.Length);
            s.Close();
            HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
            String statusCode = resp.StatusCode.ToString();
            resp.Close();
            req.Abort();
            return statusCode;
        }

        // Gets one notification based on id
        public Notification getNotification(int notificationId)
        {
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(baseUrl + "/notifications/" + notificationId + ".xml");
            req.PreAuthenticate = true;
            req.Credentials = new NetworkCredential(apiKey, "password");
            req.Method = "GET";
            req.Accept = "text/xml";

            HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
            Notification note = new Notification();

            if (resp.StatusCode == System.Net.HttpStatusCode.OK)
            {
                Stream receiveStream = resp.GetResponseStream();
                XmlReader reader = new XmlTextReader(receiveStream);

                while (reader.Read())
                {
                    if (reader.NodeType == XmlNodeType.Element)
                    {
                        if (reader.Name == "notification")
                        {
                            note = parseNotificationXML(reader.ReadOuterXml());
                        }
                    }
                }
            }
            else
            {
                throw new Exception();
            }
            resp.Close();
            req.Abort();
            return note;
        }

        public Boolean cancelNotification(int notificationId)
        {
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(baseUrl + "/notifications/" + notificationId + ".xml");
            req.PreAuthenticate = true;
            req.Credentials = new NetworkCredential(apiKey, "password");
            req.Method = "DELETE";
            req.Accept = "text/xml";

            HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
            Boolean returnValue = false;
            if (resp.StatusCode == System.Net.HttpStatusCode.OK)
            {
                returnValue = true;
            }
            else
            {
                returnValue = false;
            }
            resp.Close();
            req.Abort();
            return returnValue;
        }


        public List<Notification> getNotifications()
        {
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(baseUrl + "/notifications.xml");
            req.PreAuthenticate = true;
            req.Credentials = new NetworkCredential(apiKey, "password");
            req.Method = "GET";
            req.Accept = "text/xml";

            HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
            List<Notification> list = new List<Notification>();

            if (resp.StatusCode == System.Net.HttpStatusCode.OK)
            {
                Stream receiveStream = resp.GetResponseStream();
                XmlReader reader = new XmlTextReader(receiveStream);

                while (reader.Read())
                {
                    if (reader.NodeType == XmlNodeType.Element)
                    {
                        if (reader.Name == "notification")
                        {
                            Notification note = parseNotificationXML(reader.ReadOuterXml());
                            list.Add(note);
                        }
                    }
                }
            }
            else
            {
                throw new Exception();
            }
            resp.Close();
            req.Abort();
            return list;
        }

        private Recipient parseRecipientXML(string recipientXMLString)
        {
            XmlReader reader = new XmlTextReader(new StringReader(recipientXMLString));
            Recipient rcpt = new Recipient();
            while (reader.Read())
            {
                if (reader.NodeType == XmlNodeType.Element)
                {
                    if (reader.Name == "channel")
                    {
                        reader.Read();
                        rcpt.Channel = reader.Value;
                    }
                    else if (reader.Name == "address")
                    {
                        reader.Read();
                        rcpt.Address = reader.Value;
                    }
                    else if (reader.Name == "send_at")
                    {
                        reader.Read();
                        rcpt.SentAt = reader.Value;
                    }
                    else if (reader.Name == "status")
                    {
                        reader.Read();
                        rcpt.Status = reader.Value;
                    }
                }
            }
            return rcpt;
        }


        private Notification parseNotificationXML(string notificationXMlString)
        {
            XmlReader reader = new XmlTextReader(new StringReader(notificationXMlString));
            Notification note = new Notification();
            while (reader.Read())
            {
                if (reader.NodeType == XmlNodeType.Element)
                {
                    if (reader.Name == "id")
                    {
                        reader.Read();
                        note.Id = int.Parse(reader.Value);
                    }
                    else if (reader.Name == "escalation")
                    {
                        reader.Read();
                        note.Escalation = int.Parse(reader.Value);
                    }
                    else if (reader.Name == "body")
                    {
                        reader.Read();
                        note.Body = reader.Value;
                    }
                    else if (reader.Name == "subject")
                    {
                        reader.Read();
                        note.Subject = reader.Value;
                    }
                    else if (reader.Name == "recipients")
                    {
                        while (reader.Read())
                        {
                            if (reader.Name == "recipient" && reader.NodeType == XmlNodeType.Element)
                            {
                                Recipient newRcpt = parseRecipientXML(reader.ReadOuterXml());
                                note.addRecipient(newRcpt);
                            }
                        }
                    }
                }
            }
            return note;
        }

    }
    public class Recipient
    {

        // private member variables
        private int id;
        private int position;
        private string channel;
        private string address;
        private string status;
        private string sentAt;

        // Constructor
        public Recipient(int pos, string chan, string addr)
        {
            position = pos;
            channel = chan;
            address = addr;
        }

        public Recipient()
        {
        }

        // Properties
        public int Id
        {
            get
            {
                return id;
            }

            set
            {
                id = value;
            }
        }

        public int Position
        {
            get
            {
                return position;
            }

            set
            {
                position = value;
            }
        }

        public string Channel
        {
            get
            {
                return channel;
            }

            set
            {
                channel = value;
            }
        }

        public string Address
        {
            get
            {
                return address;
            }

            set
            {
                address = value;
            }
        }

        public string Status
        {
            get
            {
                return status;
            }

            set
            {
                status = value;
            }
        }

        public string SentAt
        {
            get
            {
                return sentAt;
            }

            set
            {
                sentAt = value;
            }
        }

    }
    public class Notification
    {
        // private member variables
        private int id;
        private int escalation;
        private string sendAt;
        private string body;
        private string subject;
        List<Recipient> recipients;

        // Constructor
        public Notification()
        {
            escalation = 10;
            recipients = new List<Recipient>();
        }

        // Properties
        public int Id
        {
            get
            {
                return id;
            }

            set
            {
                id = value;
            }
        }

        public int Escalation
        {
            get
            {
                return escalation;
            }

            set
            {
                escalation = value;
            }
        }

        public string Body
        {
            get
            {
                return body;
            }

            set
            {
                body = value;
            }
        }

        public string Subject
        {
            get
            {
                return subject;
            }

            set
            {
                subject = value;
            }
        }

        public string SendAt
        {
            get
            {
                return sendAt;
            }

            set
            {
                sendAt = value;
            }
        }

        public void addRecipient(Recipient rcpt)
        {
            recipients.Add(rcpt);
        }

        public List<Recipient> Recipients
        {
            get
            {
                return recipients;
            }
        }

        public int getNumberOfRecipients()
        {
            return recipients.Count;
        }

        public string getXML()
        {
            StringBuilder sb = new StringBuilder("<notification>");
            sb.Append("<body>");
            sb.Append(body);
            sb.Append("</body>");
            sb.Append("<subject>");
            sb.Append(subject);
            sb.Append("</subject>");
            sb.Append("<escalation>");
            sb.Append(escalation);
            sb.Append("</escalation>");
            if (sendAt != null)
            {
                sb.Append("<sendat>");
                sb.Append(sendAt);
                sb.Append("</sendat>");
            }
            sb.Append("<recipients>");
            for (int i = 0; i < getNumberOfRecipients(); i++)
            {
                sb.Append("<recipient>");
                sb.Append("<position>");
                sb.Append(recipients[i].Position);
                sb.Append("</position>");
                sb.Append("<channel>");
                sb.Append(recipients[i].Channel);
                sb.Append("</channel>");
                sb.Append("<address>");
                sb.Append(recipients[i].Address);
                sb.Append("</address>");
                sb.Append("</recipient>");
            }
            sb.Append("</recipients>");
            sb.Append("</notification>");
            return sb.ToString();
        }


    }
}
